﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using RCTools;
namespace exercice1
	{
	class Program
		{
		protected static int origRow;
		protected static int origCol;
		protected static Object lockThis = new Object();
		protected static List<Hour> listHours;
		protected static List<Thread> listThreads;

		static void Main(string[] args)
			{
			main();
			}

		private static void main()
			{
			prepareConsole();
			createHours();
			createThreads();
			startThreads();
			joinThreads();
			}

		private static void createThreads()
			{
			listThreads = new List<Thread>();
			listThreads.Add(new Thread(new ThreadStart(displayHour1)));
			listThreads.Add(new Thread(new ThreadStart(displayHour2)));
			listThreads.Add(new Thread(new ThreadStart(displayRationnal)));
			listThreads.Add(new Thread(new ThreadStart(displayHour3)));
			listThreads.Add(new Thread(new ThreadStart(displayMenu)));
			}

		private static void joinThreads()
			{
			foreach(var item in listThreads)
				{
				item.Join();
				}
			}

		private static void startThreads()
			{
			foreach(var item in listThreads)
				{
				item.Start();
				}
			}

		private static void createHours()
			{
			listHours = new List<Hour>();
			listHours.Add(new Hour());
			listHours.Add(new Hour());
			listHours.Add(new Hour());
			}

		private static void prepareConsole()
			{
			Console.SetBufferSize(1000, 1000);
			origRow = Console.CursorTop;
			origCol = Console.CursorLeft;
			}

		private static void displayMenu()
			{
			writeAt("MENU", 15, 5);
			writeAt("Press 'q' to quit", 15, 6);
			while(true)
				{
				switch(Console.ReadKey().KeyChar.ToString().ToLower())
					{
					case "q":
						Environment.Exit(0);
						break;
					default:
						break;
					}
				}
			}

		private static void displayHour1()
			{
			writeAt("Heure 1", 0, 0);
			while(true)
				{
				listHours[0].incrementSeconds(1);
				writeAt(listHours[0], 0, 2);
				Thread.Sleep(10);
				}
			}

		private static void displayHour2()
			{
			writeAt("heure 2", 50, 0);
			while(true)
				{
				listHours[1].incrementSeconds(-1);
				writeAt(listHours[1], 50, 2);
				Thread.Sleep(10);
				}
			}

		private static void displayHour3()
			{
			writeAt("heure 3 = heure 1 + heure 2", 15, 2);
			while(true)
				{
				listHours[2].add(listHours[0] + listHours[1]);
				writeAt(listHours[2], 15, 3);
				Thread.Sleep(1000);
				}
			}

		private static void displayRationnal()
			{
			int p = 0;
			while(true)
				{
				int n = listHours[0].compareTo(listHours[1]);
				switch(n)
					{
					case -1:
						if(p != n)
							{
							p = n;
							writeAt("heure 1 < heure 2", 15, 0);
							}
						break;
					case 0:
						if(p != n)
							{
							p = n;
							writeAt("heure 1 = heure 2", 15, 0);
							}
						break;
					case 1:
						if(p != n)
							{
							p = n;
							writeAt("heure 1 > heure 2", 15, 0);
							}
						break;
					default:
						break;
					}
				}
			}

		private static void writeAt(String h, int x, int y)
			{
			lock(Program.lockThis)
				{
				try
					{
					Console.SetCursorPosition(origCol + x, origRow + y);
					Console.WriteLine(h);
					}
				catch(ArgumentOutOfRangeException e)
					{
					Console.Clear();
					Console.WriteLine(e.Message);
					}
				}
			}
		}
	}
